package cn.edu.cug.cs.gtl.docsrv.doc.dao.impl;

import cn.edu.cug.cs.gtl.docsrv.config.Configuration;
import cn.edu.cug.cs.gtl.docsrv.config.FTPConfig;
import cn.edu.cug.cs.gtl.docsrv.doc.DocManager;
import cn.edu.cug.cs.gtl.docsrv.doc.FTPDocManager;
import cn.edu.cug.cs.gtl.docsrv.doc.HDFSDocManager;
import cn.edu.cug.cs.gtl.docsrv.doc.RDBDocManager;
import cn.edu.cug.cs.gtl.docsrv.doc.dao.DocDao;
import cn.edu.cug.cs.gtl.mybatis.Session;
import cn.edu.cug.cs.gtl.mybatis.mapper.doc.*;
import cn.edu.cug.cs.gtl.mybatis.metadata.DocUtils;
import cn.edu.cug.cs.gtl.net.ftp.client.ClientFTP;
import cn.edu.cug.cs.gtl.protos.TimeValue;
import cn.edu.cug.cs.gtl.protoswrapper.TimeValueWrapper;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class DocDaoImpl implements DocDao {
    public DocDaoImpl() {
        super();
    }

    @Override
    public List<DocAll> getDocData() throws Exception {
        Session session = Configuration.getSession();
        DocItemMapper docItemMapper = session.getMapper(DocItemMapper.class);
        List<DocItem> docItems = docItemMapper.selectAll();
        session.close();//及时关闭会话

        List<DocAll> docAlls = new ArrayList<>();
        for(DocItem docItem : docItems){
            DocFile docFile = new DocFile();
            docFile.setDocRawBytes(null);
            DocAll docAll = DocUtils.toDocAll(docItem,docFile);
            docAlls.add(docAll);
        }

        return docAlls;
    }

    @Override
    public boolean addDocData(DocAll docAll) throws Exception {
        String docUrl = docAll.getDocUrl();
        String[] ss = docUrl.split("/");
        String storeType = ss[0];
        // docUrl 一共三种,使用"/" 拆分，解析出第一个字段，用来区别file存储位置
        // oracle  默认放在oracle上
        // ftp://ip:port/dir/filename
        // hdfs://ip:port/dir/filename
        Session session = Configuration.getSession();
        switch (storeType){
            case "ftp:":{
                FTPConfig ftpConfig = Configuration.getFtpConfig();
                DocManager docManager = new FTPDocManager(session, ClientFTP.of(ftpConfig.getFtpIP(),
                        ftpConfig.getFtpPort(), ftpConfig.getFtpUser(),ftpConfig.getFtpPassword(),
                        ftpConfig.getFtpWorkingDirectory(),ftpConfig.getFtpType()));
                session.close();
                return docManager.insert(docAll);
            }
            case "hdfs:":{
                DocManager docManager = new HDFSDocManager(session);
                session.close();
                return docManager.insert(docAll);
            }
            default:{ // 文件默认放在oracle上
                DocManager docManager = new RDBDocManager(session);
                session.close();
                return docManager.insert(docAll);
            }
        }

    }


    @Override
    public boolean deleteDocData(BigDecimal docInternalId) throws Exception {
        Session session = Configuration.getSession();
        DocItemMapper docItemMapper = session.getMapper(DocItemMapper.class);
        DocItem docItem = docItemMapper.selectByPrimaryKey(docInternalId);
        String docUrl = docItem.getDocUrl();
        String storeType = docUrl.split("/")[0];
        //根据docUrl判断文档存储位置，使用相应的文档管理器
        switch (storeType){
            case "ftp:":{
                FTPConfig ftpConfig = Configuration.getFtpConfig();
                DocManager docManager = new FTPDocManager(session, ClientFTP.of(ftpConfig.getFtpIP(),
                        ftpConfig.getFtpPort(), ftpConfig.getFtpUser(),ftpConfig.getFtpPassword(),
                        ftpConfig.getFtpWorkingDirectory(),ftpConfig.getFtpType()));
                session.close();
                return docManager.delete(docItem);
            }
            case "hdfs:":{
                DocManager docManager = new HDFSDocManager(session);
                session.close();
                return docManager.delete(docItem);
            }
            default:{
                DocManager docManager = new RDBDocManager(session);
                session.close();
                return docManager.delete(docItem);
            }
        }
    }

    @Override
    public boolean updateDocData(DocAll docAll) throws Exception {
        Session session = Configuration.getSession();
        String docUrl = docAll.getDocUrl();
        String storeType = docUrl.split("/")[0];
        //根据docUrl判断文档存储位置，使用相应的文档管理器
        switch (storeType){
            case "ftp:":{
                FTPConfig ftpConfig = Configuration.getFtpConfig();
                DocManager docManager = new FTPDocManager(session, ClientFTP.of(ftpConfig.getFtpIP(),
                        ftpConfig.getFtpPort(), ftpConfig.getFtpUser(),ftpConfig.getFtpPassword(),
                        ftpConfig.getFtpWorkingDirectory(),ftpConfig.getFtpType()));
                session.close();
                return docManager.update(docAll);
            }
            case "hdfs:":{
                DocManager docManager = new HDFSDocManager(session);
                session.close();
                return docManager.update(docAll);
            }
            default:{
                DocManager docManager = new RDBDocManager(session);
                session.close();
                return docManager.update(docAll);
            }
        }

    }

    /**
     * 单一条件查询，可以使用的查询条件
     *     private String docEnTitle;
     *     private String docCnTitle;
     *     private String docType;
     *
     *
     * @param column
     * @param value
     * @return
     * @throws Exception
     */
    @Override
    public List<DocAll> singleQuery(String column, String value) throws Exception {
        List<DocAll> docAlls = new ArrayList<>();
        Session session = Configuration.getSession();
        DocManager docManager = new DocManager(session);
        switch (column){
            case "docEnTitle":{
                docAlls = docManager.queryByTitle(value);
            }break;
            case "docCnTitle":{
                docAlls = docManager.queryByComment(value);
            }break;
            case "docType":{
                docAlls = docManager.queryByType(value);
            }break;
        }
        session.close();
        return docAlls;
    }

    @Override
    public List<DocAll> dateQuery(TimeValue begin, TimeValue end) throws Exception {
        List<DocAll> docAlls = null;
        Session session = Configuration.getSession();
        DocManager docManager = new DocManager(session);
        docAlls = docManager.queryByAppendDate(begin,end);
        session.close();
        return docAlls;
    }

    /**
     *
     * @param docInternalId
     * @return
     * @throws Exception
     */
    @Override
    public InputStream downloadDocFile(BigDecimal docInternalId) throws Exception {
        Session session = Configuration.getSession();
        DocItemMapper docItemMapper = session.getMapper(DocItemMapper.class);
        DocItem docItem = docItemMapper.selectByPrimaryKey(docInternalId);
        String docUrl = docItem.getDocUrl();
        String storeType = docUrl.split("/")[0];
        byte[] bytes = null;
        switch (storeType){
            case "ftp:":{
                FTPConfig ftpConfig = Configuration.getFtpConfig();
                DocManager docManager = new FTPDocManager(session, ClientFTP.of(ftpConfig.getFtpIP(),
                        ftpConfig.getFtpPort(), ftpConfig.getFtpUser(),ftpConfig.getFtpPassword(),
                        ftpConfig.getFtpWorkingDirectory(),ftpConfig.getFtpType()));
                DocAll docAll = docManager.queryByInternalId(docInternalId);
                bytes = docAll.getDocRawBytes();
            }break;
            case "hdfs:":{
                DocManager docManager = new HDFSDocManager(session);
                DocAll docAll = docManager.queryByInternalId(docInternalId);
                bytes = docAll.getDocRawBytes();
            }break;
            default:{
                DocFileMapper docFileMapper = session.getMapper(DocFileMapper.class);
                DocFile docFile = docFileMapper.selectByPrimaryKey(docInternalId);
                bytes = docFile.getDocRawBytes();
            }
        }
        session.close();
        InputStream inputStream = new ByteArrayInputStream(bytes);
        return inputStream;
    }
}
